#version 300 es

#ifdef GL_ES
precision mediump float;
#endif

#define TWO_PI 6.28318530718

uniform vec2 u_resolution;
uniform float u_time;

//  Function from Iñigo Quiles
//  https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb(in vec3 c) {
  vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
  rgb = rgb * rgb * (3.0 - 2.0 * rgb);
  return c.z * mix(vec3(1.0), rgb, c.y);
}

vec3 rgb2ryb(vec3 rgb_color) {
	// Remove the white from the color
  float white = min(min(rgb_color.r, rgb_color.g), rgb_color.b);
  rgb_color -= vec3(white);

  float max_green = max(max(rgb_color.r, rgb_color.g), rgb_color.b);

	// Get the yellow out of the red & green		
  float yellow = min(rgb_color.r, rgb_color.g);
  rgb_color.r -= yellow;
  rgb_color.g -= yellow;

	// If this unfortunate conversion combines blue and green, then cut each in half to preserve the value's maximum range.
  if(rgb_color.b > 0. && rgb_color.g > 0.) {
    rgb_color.b /= 2.;
    rgb_color.g /= 2.;
  }

	// Redistribute the remaining green.
  yellow += rgb_color.g;
  rgb_color.b += rgb_color.g;

	// Normalize to values.
  float max_yellow = max(max(rgb_color.r, yellow), rgb_color.b);

  if(max_yellow > 0.) {
    float n = max_green / max_yellow;

    rgb_color.r *= n;
    yellow *= n;
    rgb_color.b *= n;
  }

	// Add the white back in.
  rgb_color.r += white;
  yellow += white;
  rgb_color.b += white;

  return vec3(rgb_color.r, yellow, rgb_color.b);
}

vec3 ryb2rgb(vec3 ryb_color) {
	// Remove the white from the color
  float white = min(min(ryb_color.r, ryb_color.g), ryb_color.b);
  ryb_color -= vec3(white);

  float max_yellow = max(max(ryb_color.r, ryb_color.g), ryb_color.b);

	// Get the green out of the yellow & blue
  float green = min(ryb_color.g, ryb_color.b);
  ryb_color.g -= green;
  ryb_color.b -= green;

  if(ryb_color.b > 0. && green > 0.) {
    ryb_color.b *= 2.;
    green *= 2.;
  }

	// Redistribute the remaining yellow.
  ryb_color.r += ryb_color.g;
  green += ryb_color.g;

	// Normalize to values.
  float max_green = max(max(ryb_color.r, green), ryb_color.b);

  if(max_green > 0.) {
    float n = max_yellow / max_green;

    ryb_color.r *= n;
    green *= n;
    ryb_color.b *= n;
  }

	// Add the white back in.
  ryb_color.r += white;
  green += white;
  ryb_color.b += white;

  return vec3(ryb_color.r, green, ryb_color.b);
}

out vec4 outColor;

void main() {

  float solution = min(u_resolution.x, u_resolution.y);
  vec2 st = (u_resolution / 2.0 - gl_FragCoord.xy) / solution;
  vec2 s = vec2(1.0, 1.0) - step(0.5, abs(st));
  if(s.x * s.y < 0.00001 || dot(st, st) > 0.25) {
    discard;
  }

  vec3 color = vec3(0.0);
  float angle = atan(st.y, st.x);
  float radius = length(st) * 2.0;

    // Map the angle (-PI to PI) to the Hue (from 0 to 1)
    // and the Saturation to the radius
  color = hsb2rgb(vec3((angle / TWO_PI) + 0.5, radius, 1.0));
  // color = rgb2ryb(color);
  color = ryb2rgb(color);
  outColor = vec4(color, smoothstep(1.0, 0.99, radius));
}
